package com.hotel.tv.application.admin.services.impl;

import com.autumn.application.dto.input.DataImportOptionInput;
import com.autumn.application.service.AbstractEditDataImportApplicationService;
import com.autumn.mybatis.wrapper.EntityQueryWrapper;
import com.autumn.util.AutoMapUtils;
import com.hotel.tv.application.admin.dto.order.OrderDetailsOutput;
import com.hotel.tv.application.admin.dto.order.OrderInput;
import com.hotel.tv.application.admin.dto.order.OrderListOutput;
import com.hotel.tv.application.admin.services.OrderService;
import com.hotel.tv.entities.Order;
import com.hotel.tv.entities.OrderItem;
import com.hotel.tv.entities.query.OrderUserQuery;
import com.hotel.tv.repositories.OrderRepository;
import com.hotel.tv.repositories.query.OrderUserQueryRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * </p>
 *
 * @description TODO
 * @author: 老码农
 * @create: 2020-04-03 11:50
 **/
@Service
public class OrderServiceImpl
        extends AbstractEditDataImportApplicationService<Long,
        Order,
        OrderRepository,
        OrderUserQuery, OrderUserQueryRepository, OrderInput, OrderInput, OrderListOutput, OrderDetailsOutput, OrderInput>
        implements OrderService {

    public OrderServiceImpl() {
        this.getSearchMembers().add("title");
    }

    @Override
    protected List<Order> dataImportHandle(List<OrderInput> items, DataImportOptionInput option) {
        List<Order> orders = new ArrayList<>(items.size());
        Map<String, Long> post = new HashMap<>(items.size());
        for (OrderInput item : items) {
            Order order = AutoMapUtils.map(item, Order.class);
            order.setOrderTime(new Date());
            order.setUserId(this.getSession().getUserId());
            orders.add(order);
        }
        return orders;
    }

    @Override
    public String getModuleName() {
        return "订单管理";
    }

    @Override
    protected void systemByCriteria(EntityQueryWrapper<OrderUserQuery> wrapper) {
        super.systemByCriteria(wrapper);
        wrapper.lambda().where().eq(OrderUserQuery::getUserId, this.getSession().getUserId());
    }

    @Override
    protected void systemByEntityCriteria(EntityQueryWrapper<Order> wrapper) {
        super.systemByEntityCriteria(wrapper);
        wrapper.lambda().where().eq(Order::getUserId, this.getSession().getUserId());
    }


    @Override
    protected void queryByOrder(EntityQueryWrapper<OrderUserQuery> query) {

        query.lambda().orderByDescending(OrderUserQuery::getOrderTime)
                .orderByDescending(OrderUserQuery::getId);
    }

    @Override
    protected Order addBefore(OrderInput orderInput, EntityQueryWrapper<Order> query) {
        Order order = super.addBefore(orderInput, query);
        order.setOrderTime(new Date());
        Long userId = this.getSession().getUserId();
        order.setUserId(userId);
        if (order.getItems() != null) {
            for (OrderItem item : order.getItems()) {
                item.setItemUserId(userId);
            }
        }
        return order;
    }

    @Override
    protected void updateBefore(OrderInput orderInput, Order entity, EntityQueryWrapper<Order> wrapper) {
        super.updateBefore(orderInput, entity, wrapper);
        Long userId = this.getSession().getUserId();
        if (entity.getItems() != null) {
            for (OrderItem item : entity.getItems()) {
                item.setItemUserId(userId);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderDetailsOutput save(OrderInput input) {
        Order order = AutoMapUtils.map(input, Order.class);
        order.setOrderTime(new Date());
        order.setUserId(this.getSession().getUserId());
        this.getRepository().insert(order);
        return AutoMapUtils.map(order, OrderDetailsOutput.class);
    }

    @Override
    public List<OrderListOutput> orders() {
        EntityQueryWrapper<OrderUserQuery> wrapper = new EntityQueryWrapper<>(OrderUserQuery.class);

        wrapper.lambda().where().eq(OrderUserQuery::getUserId, this.getSession().getUserId())
                .of().orderBy(OrderUserQuery::getOrderTime).orderBy(OrderUserQuery::getId);

        List<OrderUserQuery> orders = this.getQueryRepository().selectForList(wrapper);


        return AutoMapUtils.mapForList(orders, OrderListOutput.class);
    }


}
